﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Validation;

namespace Arquitetura.Architectural.Model
{
    [DataContract(Name = "Resultado{0}")]
    public class Resultado<T> : Resultado
    {
        #region Propriedade(s)
        [DataMember]
        public T Retorno
        { get; set; }
        #endregion Propriedade(s)

        #region Construtor(es)
        public Resultado()
            : base() { }

        public Resultado(Resultado resultado)
            : base(resultado) { }

        public Resultado(T retorno)
            : base()
        {
            Sucesso = true;
            Retorno = retorno;
        }

        public Resultado(ValidationResults validationResults)
            : base(validationResults) { }

        public Resultado(bool sucesso)
            : base(sucesso) { }

        public Resultado(T retorno, bool sucesso)
            : base(sucesso)
        {
            Retorno = retorno;
        }

        public Resultado(Exception ex)
            : base(ex) { }
        #endregion Construtor(es)
    }

    [DataContract]
    public class Resultado
    {
        #region Propriedade(s)
        [DataMember]
        public bool Sucesso
        { get; set; }

        [DataMember]
        public List<Mensagem> Mensagens
        { get; set; }
        #endregion Propriedade(s)

        #region Construtor(es)
        public Resultado() :
            this(false) { }

        public Resultado(bool sucesso)
        {
            Sucesso = sucesso;
            Mensagens = new List<Mensagem>();
        }

        public Resultado(Exception ex)
            : this(false)
        {
            Mensagem mensagem = new Mensagem(ex);
            mensagem.Informacoes.Add(ex.Message);
            Mensagens.Add(mensagem);
        }

        public Resultado(Resultado resultado)
            : this(resultado.Sucesso)
        {
            Mensagens.AddRange(resultado.Mensagens);
        }

        public Resultado(ValidationResults validationResults)
            : this(validationResults.IsValid)
        {
            if (!validationResults.IsValid)
            {
                ConsolidarResultadosValidacao(validationResults);
            }
        }
        #endregion Construtor(es)

        #region Método(s)
        public void ConsolidarResultadosValidacao(IEnumerable<ValidationResult> validationResults)
        {
            foreach (ValidationResult validationResult in validationResults)
            {
                Mensagens.Add(new Mensagem(validationResult));
                ConsolidarResultadosValidacao(validationResult.NestedValidationResults);
            }
        }

        public string ConsolidaMensagens(string separador)
        {
            if (Mensagens.Any())
            {
                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < Mensagens.Count; ++i)
                {
                    if (Mensagens[i].Informacoes.Any())
                    {
                        sb.Append(Mensagens[i].ConsolidaMensagem(separador));
                        if (i < (Mensagens.Count - 1))
                        {
                            sb.Append(separador);
                        }
                    }
                }
                return sb.ToString();
            }
            else
            {
                return string.Empty;
            }
        }
        #endregion Método(s)
    }
}
